package message

import (
	"encoding/json"
	"fmt"
	"log/slog"
	"net/http"
	"os"
	"strings"

	"gitee.com/douxuefeng/go-utils/request"
	accesstoken "gitee.com/douxuefeng/go-utils/wechat/mini/access_token"
	"gitee.com/douxuefeng/go-utils/wechat/mini/config"
	"gitee.com/douxuefeng/go-utils/wechat/mini/params"
)

const (
	mediaUrl             string = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s"
	setTypeUrl           string = "https://api.weixin.qq.com/cgi-bin/message/custom/business/typing?access_token=%s"
	mediaUploadUrl       string = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=image"
	sendCustomMessageUrl string = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s"
)

type message struct {
	*config.MiniConfig
}

func NewMessage(cfg *config.MiniConfig) *message {
	return &message{cfg}
}

func (m *message) GetTempMedia(mediaId string, fn string) (string, error) {
	token, err := accesstoken.NewAccessToken(m.MiniConfig).GetAccessToken()
	if err != nil {
		slog.Error("获取accessToken错误", "error:", err)
		return "", err
	}
	url := fmt.Sprintf(mediaUrl, token, mediaId)
	req := request.NewRequest()
	// req := request.NewDebugRequest()
	req.SetOutput(fn)
	resp, err := req.Get(url)
	if err != nil {
		return "", err
	}
	var result params.ErrResp

	if err = json.Unmarshal(resp.Body(), &result); err != nil {
		ext := strings.Split(resp.Header().Get("Content-Type"), "/")[1]
		fname := fn + "." + ext
		os.Rename(fn, fname)
		return fname, nil
	} else {
		return "", fmt.Errorf("获取临时素材失败, errcode:%d, errmsg:%s", result.Errcode, result.Errmsg)
	}
}

/**
 * @name:
 * @description:
 * @param {string} toUser 用户的 OpenID
 * @param {string} command Typing表示对用户下发"正在输入"状态 ；CancelTyping表示取消对用户的"正在输入"状态
 * @return {*}
 */
func (m *message) SetType(toUser string, command string) error {
	token, err := accesstoken.NewAccessToken(m.MiniConfig).GetAccessToken()
	if err != nil {
		slog.Error("获取accessToken错误", "error:", err)
		return err
	}
	url := fmt.Sprintf(setTypeUrl, token)
	req := request.NewRequest()
	req.SetBody(map[string]string{
		"touser":  toUser,
		"command": command,
	})
	resp, err := req.Post(url)
	if err != nil {
		return err
	}
	var result params.ErrResp
	json.Unmarshal(resp.Body(), &result)
	if result.Errcode != 0 {
		return fmt.Errorf("下发客服当前输入状态, errcode:%d, errmsg:%s", result.Errcode, result.Errmsg)
	}
	return nil
}

// https://nql.fushiwenhua.com/web/statics/img/app/goods/icon-favorite.png
func (m *message) UploadTempMedia(thumbUrl string) (string, error) {
	rsp, err := http.Get(thumbUrl)
	if err != nil {
		slog.Error("获取图片错误", "error:", err)
		return "", fmt.Errorf("获取图片错误")
	}
	defer rsp.Body.Close()
	str := strings.Split(thumbUrl, "/")
	fn := str[len(str)-1]
	token, err := accesstoken.NewAccessToken(m.MiniConfig).GetAccessToken()
	if err != nil {
		slog.Error("获取accessToken错误", "error:", err)
		return "", err
	}
	url := fmt.Sprintf(mediaUploadUrl, token)
	req := request.NewRequest()
	req.SetFileReader("media", fn, rsp.Body)
	resp, err := req.Post(url)
	if err != nil {
		return "", err
	}
	var result params.UploadTempMediaResp
	json.Unmarshal(resp.Body(), &result)
	if result.Errcode != 0 {
		return "", fmt.Errorf("上传媒体素材失败, errcode:%d, errmsg:%s", result.Errcode, result.Errmsg)
	}
	return result.MediaId, nil
}

func (m *message) SendCustomMessage(data *params.SendCustomMessageReq) error {
	token, err := accesstoken.NewAccessToken(m.MiniConfig).GetAccessToken()
	if err != nil {
		slog.Error("获取accessToken错误", "error:", err)
		return err
	}
	url := fmt.Sprintf(sendCustomMessageUrl, token)
	req := request.NewRequest()
	req.SetBody(data)
	resp, err := req.Post(url)
	if err != nil {
		return err
	}
	var result params.ErrResp
	json.Unmarshal(resp.Body(), &result)
	if result.Errcode != 0 {
		return fmt.Errorf("发送小程序消息失败, errcode:%d, errmsg:%s", result.Errcode, result.Errmsg)
	}
	return nil
}

func (m *message) SendSubcribeMessage(data *params.SendSubcribeMessageReq) error {
	var url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s"
	token, err := accesstoken.NewAccessToken(m.MiniConfig).GetAccessToken()
	if err != nil {
		return err
	}
	url = fmt.Sprintf(url, token)
	req := request.NewRequest()
	req.SetBody(data)
	resp, err := req.Post(url)
	if err != nil {
		return err
	}
	var result params.ErrResp
	json.Unmarshal(resp.Body(), &result)
	if result.Errcode != 0 {
		return fmt.Errorf("发送订阅消息失败, errcode:%d, errmsg:%s", result.Errcode, result.Errmsg)
	}
	return nil
}
